//
//  ARAudioRecordController.swift
//  AquaRaft
//
//  Created by 何启亮 on 2024/4/27.
//

import UIKit

/// 回调
protocol ARAudioRecordControllerDelegate {
    
    /// 录音结束回调
    func audioRecordControllerDidEndRecord(_ vc: ARAudioRecordController, audioPath: String, duration: TimeInterval)
    
    /// 回调错误
    func audioRecordControllerDidEndRecord(_ vc: ARAudioRecordController, withError err: Error?)
    
}

class ARAudioRecordController: ARBaseModalAlertController {

    // MARK: - Property
    
    private let audioRecordStatusViewController: BBVoiceRecordController = BBVoiceRecordController()
    
    private var audioRecordViewStatus: BBVoiceRecordState = .normal {
        didSet {
            audioRecordStatusViewController.updateUI(with: audioRecordViewStatus)
        }
    }
    
    /// 最少录音时间，如果小于等于0则表示不限制
    var minimumRecordTime: TimeInterval = 0.0
    
    /// 录音地址
    let audioRecordPath: String
    
    var audioRecorder: HQLAudioRecorder! 
    let delegate: ARAudioRecordControllerDelegate
    
    // MARK: - Init
    
    init(recordPath: String, delegate: ARAudioRecordControllerDelegate) {
        
        self.audioRecordPath = recordPath
        self.delegate = delegate
        
        super.init()
        self.autoDismiss = false
        self.bgAlpha = 0.1
        
        let url = URL.init(fileURLWithPath: recordPath)
        self.audioRecorder = HQLAudioRecorder(fileURL: url, settings: nil, delegate: self)
        
        self.modalTransitionStyle = .crossDissolve
        self.modalPresentationStyle = .overCurrentContext
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    // MARK: - LifeCycle
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        
        if audioRecordViewStatus != .recording {
            audioRecordViewStatus = .recording
        }
    }
    
    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        
        audioRecordViewStatus = .normal
    }
    
    // MARK: - Public
    
    func gestureChangeCallback(_ gesture: UILongPressGestureRecognizer) {
        
        switch gesture.state {
        case .began:
            // 开始录音
            AudioServicesPlaySystemSound(1519)
            
            if AVAudioSession.sharedInstance().category != .record {
                try? AVAudioSession.sharedInstance().setCategory(.record)
                try? AVAudioSession.sharedInstance().setActive(true)
            }
            let _ = self.audioRecorder.record()
        case .changed:
            // 判断手势
            let location = gesture.location(in: self.view)
            let bottomInputHeight = 72.0
            let bottomInputY = ARHelper.screenHeight() - bottomInputHeight - ARHelper.safeBottomHeight()
            if location.y >= bottomInputY {
                // 在正常区域
                audioRecordStatusViewController.updateUI(with: .recording)
            } else {
                audioRecordStatusViewController.updateUI(with: .releaseToCancel)
            }
        case .ended, .cancelled, .failed:
            // 结束
            if audioRecordStatusViewController.currentState() == .releaseToCancel {
                // 直接dismiss
                let _ = audioRecorder.deleteRecord()
                self.dismiss(animated: true)
                return
            }
            audioRecorder.stop { [weak self] in
                DispatchQueue.main.async {
                    self?.dismiss(animated: true)
                }
            }
        default: break
        }
    }
    
}

extension ARAudioRecordController: HQLAudioRecorderDelegate {
    
    func audioRecorderDidFinishRecording(_ recorder: AudioRecordProvider) {
        DispatchQueue.main.async {
            self.delegate.audioRecordControllerDidEndRecord(self, audioPath: self.audioRecordPath, duration: recorder.duration.seconds)
        }
        
    }
    
    func audioRecorderReceiveError(_ recorder: AudioRecordProvider, error: Error?) {
        DispatchQueue.main.async {
            self.delegate.audioRecordControllerDidEndRecord(self, withError: error)
        }
    }
    
    func audioRecorderRecordCallback(_ recorder: AudioRecordProvider) {
        let averagePower = self.powerToPercentage(power: self.audioRecorder.averagePower())
        DispatchQueue.main.async {
            self.audioRecordStatusViewController.updatePower(averagePower)
        }
    }
    
    // Tool
    
    func powerToPercentage(power: Float) -> Float {
        let minDb: Float = -50
        let maxDb: Float = 0
        if power < minDb {
            return 0
        } else if power >= maxDb {
            return 1
        } else {
            return (power - minDb) / (maxDb - minDb)
        }
    }
    
}
